package cn.demoncat.util.mysql.util;

import cn.demoncat.util.lang.IntegerUtil;
import cn.demoncat.util.lang.JDBCUtil;
import cn.demoncat.util.lang.constant.JDBCConstant;
import cn.demoncat.util.lang.constant.StringConstant;
import cn.demoncat.util.lang.entity.LinkedMapSs;
import cn.demoncat.util.lang.entity.MapSs;
import cn.demoncat.util.lang.fn.ConsumerThrow;
import cn.demoncat.util.lang.fn.FunctionThrow;
import cn.demoncat.util.mysql.entity.*;
import org.apache.commons.lang3.StringUtils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;

/**
 * Mysql工具
 *
 * @author 延晓磊
 * @since 2020年10月09日
 */
public class MysqlUtil {

    // 数据库类型
    public static final int DB_TYPE = 1;
    // 数据库端口
    public static final int DB_PORT = 3306;

    /**
     * 查询字段详情
     *
     * @param host
     * @param user
     * @param password
     * @param dbName
     * @param tableName
     * @return
     *
     * @author 延晓磊
     *
     * @since 2017年8月11日
     */
    public static List<MysqlColumn> listColumnInfo(String host, String user, String password, String dbName, String tableName) {
        return queryInfo(host, user, password, "SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,DATA_TYPE,COLUMN_DEFAULT,IS_NULLABLE,COLUMN_KEY,CHARACTER_MAXIMUM_LENGTH FROM `COLUMNS` WHERE TABLE_SCHEMA='"+dbName+"' AND TABLE_NAME ='"+tableName+"';", rs -> new MysqlColumn(rs.getString("COLUMN_NAME"),rs.getString("COLUMN_COMMENT"),rs.getString("COLUMN_TYPE"),rs.getString("DATA_TYPE"),rs.getString("COLUMN_DEFAULT"),rs.getString("IS_NULLABLE"),rs.getString("COLUMN_KEY"),rs.getString("CHARACTER_MAXIMUM_LENGTH")));
    }

    /**
     * 查询表详情：{表,字段集}
     *
     * @param host
     * @param user
     * @param password
     * @param dbName
     * @param tableName
     *
     * @return
     *
     * @author 延晓磊
     *
     * @since 2017年8月11日
     */
    public static MysqlTable getTableInfo(String host, String user, String password, String dbName, String tableName) {
        MysqlTable table = new MysqlTable();
        queryInfos(host,user,password,connection -> {
            // 查询表信息
            JDBCUtil.query(connection, "SELECT TABLE_NAME,TABLE_COMMENT,`ENGINE`,CREATE_TIME FROM `TABLES` WHERE TABLE_SCHEMA = '" + dbName +"' AND TABLE_NAME ='"+tableName+"';", r ->{
                table.setName(r.getString("TABLE_NAME"));
                table.setComment(r.getString("TABLE_COMMENT"));
                table.setEngine(r.getString("ENGINE"));
                table.setCreateTime(r.getString("CREATE_TIME"));
            });
            // 查询字段信息
            table.setColumns(JDBCUtil.queryList(connection, "SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,DATA_TYPE,COLUMN_DEFAULT,IS_NULLABLE,COLUMN_KEY,CHARACTER_MAXIMUM_LENGTH FROM `COLUMNS` WHERE TABLE_SCHEMA='"+dbName+"' AND TABLE_NAME ='"+tableName+"';", r -> new MysqlColumn(r.getString("COLUMN_NAME"),r.getString("COLUMN_COMMENT"),r.getString("COLUMN_TYPE"),r.getString("DATA_TYPE"),r.getString("COLUMN_DEFAULT"),r.getString("IS_NULLABLE"),r.getString("COLUMN_KEY"),r.getString("CHARACTER_MAXIMUM_LENGTH"))));
        });
        return table;
    }

    /**
     * 查询表详情：{表,字段集}
     *
     * @param host
     * @param user
     * @param password
     * @param dbName
     * @param tableNames
     *
     * @return
     *
     * @author 延晓磊
     *
     * @since 2017年8月11日
     */
    public static List<MysqlTable> listTableInfo(String host, String user, String password, String dbName, List<String> tableNames) {
        List<MysqlTable> list = new ArrayList<>();
        queryInfos(host,user,password,connection -> {
            for (String tableName : tableNames) {
                MysqlTable table = new MysqlTable();
                // 查询表信息
                JDBCUtil.query(connection, "SELECT TABLE_NAME,TABLE_COMMENT,`ENGINE`,CREATE_TIME FROM `TABLES` WHERE TABLE_SCHEMA = '" + dbName +"' AND TABLE_NAME ='"+tableName+"';", r ->{
                    table.setName(r.getString("TABLE_NAME"));
                    table.setComment(r.getString("TABLE_COMMENT"));
                    table.setEngine(r.getString("ENGINE"));
                    table.setCreateTime(r.getString("CREATE_TIME"));
                });
                // 查询字段信息
                table.setColumns(JDBCUtil.queryList(connection, "SELECT COLUMN_NAME,COLUMN_COMMENT,COLUMN_TYPE,DATA_TYPE,COLUMN_DEFAULT,IS_NULLABLE,COLUMN_KEY,CHARACTER_MAXIMUM_LENGTH FROM `COLUMNS` WHERE TABLE_SCHEMA='"+dbName+"' AND TABLE_NAME ='"+tableName+"';", r -> new MysqlColumn(r.getString("COLUMN_NAME"),r.getString("COLUMN_COMMENT"),r.getString("COLUMN_TYPE"),r.getString("DATA_TYPE"),r.getString("COLUMN_DEFAULT"),r.getString("IS_NULLABLE"),r.getString("COLUMN_KEY"),r.getString("CHARACTER_MAXIMUM_LENGTH"))));
                list.add(table);
            }
        });
        return list;
    }

    /**
     * 查询表详情
     *
     * @param host
     * @param user
     * @param password
     * @param dbName
     * @return
     *
     * @author 延晓磊
     *
     * @since 2017年8月11日
     */
    public static List<MysqlTable> listTableInfo(String host, String user, String password, String dbName) {
        return queryInfo(host, user, password, "SELECT TABLE_NAME,TABLE_COMMENT,`ENGINE`,CREATE_TIME FROM `TABLES` WHERE TABLE_SCHEMA = '" + dbName + ";", rs -> new MysqlTable(rs.getString("TABLE_NAME"),rs.getString("TABLE_COMMENT"),rs.getString("ENGINE"),rs.getString("CREATE_TIME")));
    }

    /**
     * 查询表Map - {名称:注释}
     *
     * @param host
     * @param user
     * @param password
     * @param dbName
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Map<String,String> mapTable(String host, String user, String password, String dbName){
        List<MysqlTable> tables = listTableInfo(host, user, password, dbName);
        Map<String, String> ts = new LinkedHashMap<>();
        for (MysqlTable table : tables) {
            ts.put(table.getName(),  StringUtils.isBlank(table.getComment()) ? StringConstant.EMPTY : (table.getComment().endsWith("表") ? table.getComment().substring(0, table.getComment().length()-1) : table.getComment()));
        }
        return ts;
    }

    /**
     * 查询表名称
     *
     * @param host
     * @param user
     * @param password
     * @param dbName
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<String> listTable(String host, String user, String password, String dbName){
        return queryList(dbName, host, user, password, "SHOW TABLES;", rs -> rs.getString(1));
    }

    /**
     * 打开的表
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<OpenTable> listOpenTable(String host, String user, String password){
        return queryList(host, user, password, "SHOW OPEN TABLES;", rs -> new OpenTable(rs.getString(1), rs.getString(2), IntegerUtil.valueOf(rs.getString(3))));
    }

    /**
     * InnoDB事务、锁。锁等待、打开的表
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月11日
     */
    public static Map<String,Object> listInnodb(String host, String user, String password){
        Map<String,Object> map = new HashMap<>();
        // 查询数据库
        queries(host, user, password, connection -> {
            // 查询事务
            map.put("trx", JDBCUtil.queryList(connection, "SELECT trx_id,trx_state,trx_started,trx_requested_lock_id,trx_wait_started,trx_mysql_thread_id,trx_query,trx_operation_state,trx_tables_in_use,trx_tables_locked,trx_rows_locked,trx_rows_modified,trx_isolation_level FROM information_schema.INNODB_TRX;", rs -> new InnodbTrx(rs.getString("trx_id"), rs.getString("trx_state"), rs.getString("trx_started"), rs.getString("trx_requested_lock_id"), rs.getString("trx_wait_started"), rs.getString("trx_mysql_thread_id"), rs.getString("trx_query"), rs.getString("trx_operation_state"), rs.getString("trx_tables_in_use"), rs.getString("trx_tables_locked"), rs.getString("trx_rows_locked"), rs.getString("trx_rows_modified"), rs.getString("trx_isolation_level"))));
            // 查询锁
            map.put("lock", JDBCUtil.queryList(connection, "SELECT lock_id,lock_trx_id,lock_mode,lock_type,lock_table FROM information_schema.INNODB_LOCKS;", rs -> new InnodbLock(rs.getString("lock_id"), rs.getString("lock_trx_id"), rs.getString("lock_mode"), rs.getString("lock_type"), rs.getString("lock_table"))));
            // 查询锁等待
            map.put("lockWait", JDBCUtil.queryList(connection,"SELECT requesting_trx_id,requested_lock_id,blocking_trx_id,blocking_lock_id FROM information_schema.INNODB_LOCK_WAITS;", rs -> new InnodbLockWait(rs.getString("requesting_trx_id"), rs.getString("requested_lock_id"), rs.getString("blocking_trx_id"), rs.getString("blocking_lock_id"))));
            // 查询打开的表
            map.put("openTable", JDBCUtil.queryList(connection, "SHOW OPEN TABLES;", rs -> new OpenTable(rs.getString(1), rs.getString(2), IntegerUtil.valueOf(rs.getString(3)))));
        });
        return map;
    }

    /**
     * InnoDB事务
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<InnodbTrx> listTrx(String host, String user, String password){
        return queryList(host, user, password, "SELECT trx_id,trx_state,trx_started,trx_requested_lock_id,trx_wait_started,trx_mysql_thread_id,trx_query,trx_operation_state,trx_tables_in_use,trx_tables_locked,trx_rows_locked,trx_rows_modified,trx_isolation_level FROM information_schema.INNODB_TRX;", rs -> new InnodbTrx(rs.getString("trx_id"), rs.getString("trx_state"), rs.getString("trx_started"), rs.getString("trx_requested_lock_id"), rs.getString("trx_wait_started"), rs.getString("trx_mysql_thread_id"), rs.getString("trx_query"), rs.getString("trx_operation_state"), rs.getString("trx_tables_in_use"), rs.getString("trx_tables_locked"), rs.getString("trx_rows_locked"), rs.getString("trx_rows_modified"), rs.getString("trx_isolation_level")));
    }

    /**
     * InnoDB锁等待
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<InnodbLockWait> listLockWait(String host, String user, String password){
        return queryList(host, user, password, "SELECT requesting_trx_id,requested_lock_id,blocking_trx_id,blocking_lock_id FROM information_schema.INNODB_LOCK_WAITS;", rs -> new InnodbLockWait(rs.getString("requesting_trx_id"), rs.getString("requested_lock_id"), rs.getString("blocking_trx_id"), rs.getString("blocking_lock_id")));
    }

    /**
     * InnoDB锁
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<InnodbLock> listLock(String host, String user, String password){
        return queryList(host, user, password, "SELECT lock_id,lock_trx_id,lock_mode,lock_type,lock_table FROM information_schema.INNODB_LOCKS;", rs -> new InnodbLock(rs.getString("lock_id"), rs.getString("lock_trx_id"), rs.getString("lock_mode"), rs.getString("lock_type"), rs.getString("lock_table")));
    }

    /**
     * 用户信息+连接
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<MysqlUser> listUsers(String host, String user, String password){
        List<MysqlUser> list = new ArrayList<>();
        // 查询数据库
        queries(host, user, password, connection -> {
            // 用户信息
            JDBCUtil.query(connection, "SELECT host,user,password_last_changed,account_locked,select_priv,insert_priv,update_priv,delete_priv,alter_priv,process_priv FROM mysql.user;", rs -> list.add(new MysqlUser(rs.getString("user"), rs.getString("host"), rs.getString("password_last_changed"), rs.getString("account_locked"),rs.getString("select_priv"),rs.getString("insert_priv"),rs.getString("update_priv"),rs.getString("delete_priv"),rs.getString("alter_priv"),rs.getString("process_priv"))));
            // 连接信息
            List<MysqlUser> list2 = JDBCUtil.queryList(connection, "SELECT user,host,current_connections,total_connections FROM performance_schema.accounts;", rs -> new MysqlUser(rs.getString("user"), rs.getString("host"), rs.getString("current_connections"), rs.getString("total_connections")));
            // 整合
            for (MysqlUser u : list) {
                for (MysqlUser u2 : list2) {
                    if (u.getHost().equals(u2.getHost()) && u.getUser().equals(u2.getUser())) {
                        if (u.getCurrConn() == null) {
                            u.setCurrConn(u2.getCurrConn());
                            u.setTotalConn(u2.getTotalConn());
                        }else{
                            u.setCurrConn(u.getCurrConn() + u2.getCurrConn());
                            u.setTotalConn(u.getTotalConn() + u2.getTotalConn());
                        }
                        u2.setHost(null);
                        break;
                    }
                }
            }
        });
        return list;
    }

    /**
     * 用户连接
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<MysqlUser> listUserConn(String host, String user, String password){
        return queryList(host, user, password, "SELECT user,host,current_connections,total_connections FROM performance_schema.accounts;", rs -> new MysqlUser(rs.getString("user"), rs.getString("host"), rs.getString("current_connections"), rs.getString("total_connections")));
    }

    /**
     * 用户列表
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<MysqlUser> listUser(String host, String user, String password){
        return queryList(host, user, password, "SELECT host,user,password_last_changed,account_locked,select_priv,insert_priv,update_priv,delete_priv,alter_priv,process_priv FROM mysql.user;", rs -> new MysqlUser(rs.getString("user"), rs.getString("host"), rs.getString("password_last_changed"), rs.getString("account_locked"),rs.getString("select_priv"),rs.getString("insert_priv"),rs.getString("update_priv"),rs.getString("delete_priv"),rs.getString("alter_priv"),rs.getString("process_priv")));
    }

    /**
     * 杀死线程（处理死锁、执行时间过长等问题线程）
     *
     * @param id    线程ID
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void killProcess(String host, String user, String password, String id){
        execute(host, user, password, "KILL " + id);
    }

    /**
     * 查询线程
     * <pre>
     * 注：非root用户只能看到自己的线程，需要进行授权 >>
     *      GRANT PROCESS ON *.* to reader;
     *      FLUSH PRIVILEGES;
     * </pre>
     * @param host
     * @param user
     * @param password
     * @param isFull    是否显示完整执行语句
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<MysqlProcess> listProcess(String host, String user, String password, boolean isFull){
        return queryList(host, user, password, isFull ? "SHOW FULL PROCESSLIST;" : "SHOW PROCESSLIST;", rs -> new MysqlProcess(rs.getString("Id"), rs.getString("User"), rs.getString("Host"), rs.getString("db"),rs.getString("Command"),rs.getString("Time"),rs.getString("State"),rs.getString("Info")));
    }

    /**
     * 查询全局状态+变量
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Map<String,Map<String,String>> listVarAndStatus(String host, String user, String password){
        Map<String,Map<String,String>> map = new HashMap<>();
        // 查询数据库
        queries(host, user, password, connection -> {
            // 查询变量
            MapSs vars = MapSs.getInstance();
            JDBCUtil.query(connection, "SHOW GLOBAL VARIABLES;", rs -> vars.put(rs.getString(1), rs.getString(2)));
            map.put("vars", filterVars(vars));
            // 查询状态
            MapSs status = MapSs.getInstance();
            JDBCUtil.query(connection, "SHOW GLOBAL STATUS;", rs -> status.put(rs.getString(1), rs.getString(2)));
            map.put("status", filterStatus(status));
        });
        return map;
    }

    /**
     * 查询全局状态 - 系统状态、统计
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Map<String,String> listStatus(String host, String user, String password){
        MapSs vars = MapSs.getInstance();
        // 查询数据库
        query(host, user, password, "SHOW GLOBAL STATUS;", rs -> vars.put(rs.getString(1), rs.getString(2)));
        return filterStatus(vars);
    }

    /**
     * 查询全局变量 - 系统/配置信息
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Map<String,String> listVars(String host, String user, String password){
        MapSs vars = MapSs.getInstance();
        // 查询数据库
        query(host, user, password, "SHOW GLOBAL VARIABLES;", rs -> vars.put(rs.getString(1), rs.getString(2)));
        return filterVars(vars);
    }

    /**
     * 查询所有数据库
     *
     * @param host
     * @param user
     * @param password
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static List<String> listDbs(String host, String user, String password){
        // 查询数据库
        List<String> dbs = queryList(host, user, password, "SHOW DATABASES;", rs -> rs.getString(1));
        // 去除系统库
        dbs.removeAll(JDBCConstant.MysqlSysDb.LIST);
        return dbs;
    }

    /**
     * 连接数据库服务器，执行操作语句
     *
     * @param host
     * @param user
     * @param password
     * @param sql	执行语句，如 "kill 123"
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void execute(String host, String user, String password, String sql){
        JDBCUtil.execute(DB_TYPE,host,DB_PORT,user,password,sql);
    }

    /**
     * 连接数据库服务器，执行查询语句
     *
     * @param host
     * @param user
     * @param password
     * @param sql	查询语句，如"SHOW DATABASES;"
     * @param fn	查询回调，获取执行结果
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void query(String host, String user, String password, String sql, ConsumerThrow<ResultSet,SQLException> fn){
        JDBCUtil.query(DB_TYPE,host,DB_PORT,user,password,sql,fn);
    }

    /**
     * 连接数据库服务器，执行查询语句
     *
     * @param host
     * @param user
     * @param password
     * @param sql	查询语句，如"SHOW DATABASES;"
     * @param fn	查询回调，获取执行结果
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static <R>R queryOne(String host, String user, String password, String sql, FunctionThrow<ResultSet,R,SQLException> fn){
        return JDBCUtil.queryOne(DB_TYPE,host,DB_PORT,user,password,sql,fn);
    }

    /**
     * 连接数据库服务器，执行查询语句
     *
     * @param host
     * @param user
     * @param password
     * @param sql	查询语句，如"SHOW DATABASES;"
     * @param fn	查询回调，获取执行结果
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static <R>List<R> queryList(String host, String user, String password, String sql, FunctionThrow<ResultSet,R,SQLException> fn){
        return JDBCUtil.queryList(DB_TYPE,host,DB_PORT,user,password,sql,fn);
    }

    /**
     * 连接数据库服务器，执行批量查询语句
     *
     * @param host
     * @param user
     * @param password
     * @param fn	查询操作
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void queries(String host, String user, String password, ConsumerThrow<Connection,SQLException> fn){
        JDBCUtil.queries(DB_TYPE,host,DB_PORT,user,password,fn);
    }

    /**
     * 连接数据库，执行查询语句
     *
     * @param dbName 数据库
     * @param host
     * @param user
     * @param password
     * @param sql	查询语句
     * @param fn	查询回调，获取执行结果
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void query(String dbName, String host, String user, String password, String sql, ConsumerThrow<ResultSet,SQLException> fn){
        JDBCUtil.query(dbName, DB_TYPE, host, DB_PORT, user, password, sql, fn);
    }

    /**
     * 连接数据库，执行查询语句，获取单条结果
     *
     * @param dbName 数据库
     * @param host
     * @param user
     * @param password
     * @param sql	查询语句
     * @param fn	查询回调，获取执行结果
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static <R>R queryOne(String dbName, String host, String user, String password, String sql, FunctionThrow<ResultSet,R,SQLException> fn){
        return JDBCUtil.queryOne(dbName, DB_TYPE, host, DB_PORT, user, password, sql, fn);
    }

    /**
     * 连接数据库，执行查询语句，获取多条结果
     *
     * @param dbName 数据库
     * @param host
     * @param user
     * @param password
     * @param sql	查询语句
     * @param fn	查询回调，获取执行结果
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static <R>List<R> queryList(String dbName, String host, String user, String password, String sql, FunctionThrow<ResultSet,R,SQLException> fn){
        return JDBCUtil.queryList(dbName, DB_TYPE, host, DB_PORT, user, password, sql, fn);
    }

    /**
     * 连接数据库，执行批量查询语句
     *
     * @param dbName 数据库
     * @param host
     * @param user
     * @param password
     * @param fn	查询操作
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void queries(String dbName, String host, String user, String password, ConsumerThrow<Connection,SQLException> fn){
        JDBCUtil.queries(dbName, DB_TYPE, host, DB_PORT, user, password, fn);
    }

    /**
     * 连接数据库information_schema表，执行查询语句
     *
     * @param host
     * @param user
     * @param password
     * @param sql	查询语句
     * @param fn	查询回调，获取执行结果
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static <R>List<R> queryInfo(String host, String user, String password, String sql, FunctionThrow<ResultSet,R,SQLException> fn){
        return JDBCUtil.queryInfo(DB_TYPE, host, DB_PORT, user, password, sql, fn);
    }

    /**
     * 连接数据库information_schema表，执行批量查询语句
     *
     * @param host
     * @param user
     * @param password
     * @param fn	查询操作
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void queryInfos(String host, String user, String password, ConsumerThrow<Connection,SQLException> fn){
        JDBCUtil.queryInfos(DB_TYPE, host, DB_PORT, user, password, fn);
    }

    /**
     * 注册驱动
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static void registerDriver() throws ClassNotFoundException {
        Class.forName(JDBCUtil.getDriver(DB_TYPE));
    }

    /**
     * 创建连接 - 服务器
     *
     * @param host
     * @param user
     * @param password
     * @return
     * @throws SQLException
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Connection getConnection(String host, String user, String password) throws SQLException {
        return DriverManager.getConnection(JDBCUtil.getUrl(DB_TYPE, host+":"+DB_PORT), user, password);
    }

    /**
     * 创建连接 - 数据库
     *
     * @param host
     * @param user
     * @param password
     * @return
     * @throws SQLException
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Connection getConnection(String dbName, String host, String user, String password) throws SQLException {
        return DriverManager.getConnection(JDBCUtil.getUrl(DB_TYPE, host+":"+DB_PORT, dbName), user, password);
    }

    /**
     * 创建连接 - information_schema库（信息查询）
     *
     * @param host
     * @param user
     * @param password
     * @return
     * @throws SQLException
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Connection getInfoConnection(String host, String user, String password) throws SQLException {
        return DriverManager.getConnection(JDBCUtil.getInfoUrl(DB_TYPE, host+":"+DB_PORT), user, password);
    }

    /**
     * 创建连接 - performance_schema库的URL（性能查询）
     *
     * @param host
     * @param user
     * @param password
     * @return
     * @throws SQLException
     *
     * @author 延晓磊
     * @since 2020年10月09日
     */
    public static Connection getPrefConnection(String host, String user, String password) throws SQLException {
        return DriverManager.getConnection(JDBCUtil.getPerfUrl(DB_TYPE, host+":"+DB_PORT), user, password);
    }

    /**
     * 过滤全局状态
     *
     * @param vars
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月10日
     */
    public static Map<String,String> filterStatus(Map<String,String> vars){
        LinkedMapSs map = new LinkedMapSs();
        // 累计启动时间
        map.put("uptime", vars.get("Uptime"));
        // 当前活跃线程
        map.put("threads_running", vars.get("Threads_running"));
        // 当前连接线程
        map.put("threads_connected", vars.get("Threads_connected"));
        // 累计等待表锁次数
        map.put("table_locks_waited", vars.get("Table_locks_waited"));
        // 累计慢查询次数
        map.put("slow_queries", vars.get("Slow_queries"));
        // 最后连接时间
        map.put("max_used_connections_time", vars.get("Max_used_connections_time"));
        // 最大连接数
        map.put("max_used_connections", vars.get("Max_used_connections"));
        // 被锁的连接
        map.put("locked_connects", vars.get("Locked_connects"));
        // 累计连接数
        map.put("connections", vars.get("Connections"));
        // 累计锁表次数
        map.put("com_lock_tables", vars.get("Com_lock_tables"));
        map.put("com_unlock_tables", vars.get("Com_unlock_tables"));
        // 累计更新次数
        map.put("com_update", vars.get("Com_update"));
        // 累计插入次数
        map.put("com_insert", vars.get("Com_insert"));
        // 累计删除次数
        map.put("com_delete", vars.get("Com_delete"));
        // 累计查询次数
        map.put("com_select", vars.get("Com_select"));
        // 累计回滚次数
        map.put("com_rollback", vars.get("Com_rollback"));
        // 累计提交次数
        map.put("com_commit", vars.get("Com_commit"));
        // 累计接收数据
        map.put("bytes_received", vars.get("Bytes_received"));
        // 累计发送数据
        map.put("bytes_sent", vars.get("Bytes_sent"));
        return map;
    }

    /**
     * 过滤全局变量
     *
     * @param vars
     * @return
     *
     * @author 延晓磊
     * @since 2020年10月10日
     */
    public static Map<String,String> filterVars(Map<String,String> vars){
        LinkedMapSs map = new LinkedMapSs();
        // HOST、端口
        map.put("hostname", vars.get("hostname"));
        map.put("port", vars.get("port"));
        // 系统版本
        map.put("version_compile_os", vars.get("version_compile_os"));
        map.put("version_comment", vars.get("version_comment"));
        map.put("version", vars.get("version"));
        // 字符集
        map.put("character_set_server", vars.get("character_set_server"));
        // SQL模式
        map.put("sql_mode", vars.get("sql_mode"));
        // 连接
        map.put("max_connections", vars.get("max_connections"));
        map.put("max_allowed_packet", vars.get("max_allowed_packet"));
        // 连接等待超时(默认28800，即8小时，超时将关闭sleep的连接)
        map.put("wait_timeout", vars.get("wait_timeout"));
        // innodb
        map.put("default_storage_engine", vars.get("default_storage_engine"));
        map.put("innodb_lock_wait_timeout", vars.get("innodb_lock_wait_timeout"));
        // 事务隔离级别
        map.put("transaction_isolation", vars.get("transaction_isolation"));
        // 数据目录
        map.put("datadir", vars.get("datadir"));
        // binlog
        map.put("binlog_format", vars.get("binlog_format"));
        map.put("log_bin", vars.get("log_bin"));
        // 慢查询
        map.put("slow_query_log_file", vars.get("slow_query_log_file"));
        map.put("slow_query_log", vars.get("slow_query_log"));
        map.put("long_query_time", vars.get("long_query_time"));
        // 错误日志目录
        map.put("log_error", vars.get("log_error"));
        // 错误日志级别：1 错误信息；2  错误信息和告警信息； 3：错误信息、告警信息和通知信息
        map.put("log_error_verbosity", vars.get("log_error_verbosity"));
        // 运行日志
        map.put("general_log", vars.get("general_log"));
        map.put("general_log_file", vars.get("general_log_file"));
        return map;
    }
}
